"""
This is a vector
Decide on what vector implementation to use
"""
# FIXME - do something about this
import Numeric as N, maths

class Vector:
	def __init__(self, vector = None, x = 0.0, y = 0.0, z = 0.0):
		"""
		Initialise from either a vector, or components
		"""
		#FIXME - do we need to handle matrixes as initialisers
		self.len = 0.0
		self.lenCalculated = False
		self.normalised = False
		if vector != None:
			self.repr = N.array(vector.repr)
		else:
			self.repr = N.array(x, y, z)		
		self.len = self.length()

	def length(self):
		lenSqrd = N.dot(self.repr, self.repr)
		self.len = math.sqrt(lenSqrd)
		self.lenCalculated = True
		return self.len
	def cross(self, otherVec):
		u = self.repr
		v = otherVec.repr
	def __len__(self):
		"""
		This is a 3 component vector
		"""
		if not self.lenCalculated:
			self.length()
		return self.len
	def __getitem__(self, key):
		"""
		We assume non-insanity for speed.
		Be careful calling this function.
		"""
		return self.repr[key]
	def normalise(self):
		#FIXME- using numpy internal goo is faster
		self.normalised = True
		if not self.lenCalculated:
			self.length()
		self.repr = N.divide(self.repr, self.len)
		self.normalised = True
	def negate(self):
		self.repr = N.multiply(self.repr, -1)
		self.normalised = False
		self.length()
	def __iadd__(self, v):
		self.repr = N.add(self.repr, v.repr)
	def __isub__(self, v):
		self.repr = N.subtract(self.repr, v.repr)
	def __add__(self, v):
		return N.add(self.repr, v)
	def __sub__(self, v):
		return N.subtract(self.repr, v)

class Vector2:
    def __init__(self, x = 0.0, y = 0.0):
        self.x = x
        self.y = y
    def clone(self):
        return Vector(self.x, self.y)
    def tuple(self):
        return (self.x, self.y)
    def distance(self, other):
        x_diff = other.x - self.x
        y_diff = other.y - self.y
        sq = (x_diff * x_diff) + (y_diff * y_diff)
        return math.sqrt(sq)
    def normalise(self, weight = 1.0):
        sq = (self.x * self.x) + (self.y * self.y)
        length = math.sqrt(sq)
        length /= float(weight)
        self.x /= length
        self.y /= length
    def is_close(self, other, delta = 3.01):
        x_diff = abs(self.x - other.x)
        y_diff = abs(self.y - other.y)
        if x_diff < delta and y_diff < delta:
            return True
        return False
    def __iadd__(self, other):
        self.x += other.x
        self.y += other.y
        return self
    def __add__(self, other):
        v = Vector(self.x, self.y)
        v.x += other.x
        v.y += other.y
        return v
    def __mul__(self, other):
        v = Vector(self.x, self.y)
        v.x *= other
        v.y *= other
        return v
    def __sub__(self, other):
        v = Vector(self.x, self.y)
        v.x -= other.x
        v.y -= other.y
        return v

